병행과 병렬

public class Bank {
int moneyBox;
public void putMoney(int money) {
moneyBox = money;
}
public int getMoney() {
int rs = moneyBox;
moneyBox = 0;
return rs;
}
public static void main(String[] args) {
Bank bank = new Bank();
Person person1 = new Person("선웅", 10000, bank);
Person person2 = new Person("용운", 4000, bank);
Person person3 = new Person("도훈", 500000, bank);
person1.start();
person2.start();
person3.start();
}
}
public class Person extends Thread {
private String name;
private int myMoney=0;
private Bank bank;
public Person(String name, int myMoney, Bank bank) {
this.name = name;
this.myMoney = myMoney;
this.bank = bank;
}
public void run() {
while(true) {
bank.putMoney(myMoney);
System.out.println(name + "님께서 " + myMoney + "원을 입금하셨습니다.");
myMoney = bank.getMoney();
System.out.println(name + "님께서 " + myMoney + "원을 출금하셨습니다.");
System.out.println("현재 " + name + "님께서는 " + myMoney + "원을 가지고 있습니다.");
}
}
}
내 돈을 찾아주세효~
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
용운님께서 4000원을 입금하셨습니다.
도훈님께서 500000원을 입금하셨습니다.
선웅님께서 500000원을 출금하셨습니다.
용운님께서 0원을 출금하셨습니다.
도훈님께서 0원을 출금하셨습니다.
현재 선웅님께서는 500000원을 가지고 있습니다.
현재 용운님께서는 0원을 가지고 있습니다.
현재 도훈님께서는 0원을 가지고 있습니다.
선웅님께서 500000원을 입금하셨습니다.
용운님께서 0원을 입금하셨습니다.
도훈님께서 0원을 입금하셨습니다.
선웅님께서 0원을 출금하셨습니다.
생략...
public class Person extends Thread {
private String name;
private int myMoney=0;
private Bank bank;
static private Object police = new Object(); // 경찰 한명 둔다.
public Person(String name, int myMoney, Bank bank) {
this.name = name;
this.myMoney = myMoney;
this.bank = bank;
}
public void run() {
synchronized(police) { // 경찰이 감시한다. 한번에 한사람만 접근가능하다.
bank.putMoney(myMoney);
System.out.println(name + "님께서 " + myMoney + "원을 입금하셨습니다.");
myMoney = bank.getMoney();
System.out.println(name + "님께서 " + myMoney + "원을 출금하셨습니다.");
System.out.println("현재 " + name + "님께서는 " + myMoney + "원을 가지고 있습니다.");
}
}
}
경찰을 둔다
도훈님께서 500000원을 입금하셨습니다.
도훈님께서 500000원을 출금하셨습니다.
현재 도훈님께서는 500000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
용운님께서 4000원을 입금하셨습니다.
용운님께서 4000원을 출금하셨습니다.
현재 용운님께서는 4000원을 가지고 있습니다.
도훈님께서 500000원을 입금하셨습니다.
도훈님께서 500000원을 출금하셨습니다.
현재 도훈님께서는 500000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
용운님께서 4000원을 입금하셨습니다.
용운님께서 4000원을 출금하셨습니다.
현재 용운님께서는 4000원을 가지고 있습니다.
도훈님께서 500000원을 입금하셨습니다.
도훈님께서 500000원을 출금하셨습니다.
현재 도훈님께서는 500000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
용운님께서 4000원을 입금하셨습니다.
용운님께서 4000원을 출금하셨습니다.
현재 용운님께서는 4000원을 가지고 있습니다.
도훈님께서 500000원을 입금하셨습니다.
도훈님께서 500000원을 출금하셨습니다.
현재 도훈님께서는 500000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
용운님께서 4000원을 입금하셨습니다.
용운님께서 4000원을 출금하셨습니다.
현재 용운님께서는 4000원을 가지고 있습니다.
도훈님께서 500000원을 입금하셨습니다.
도훈님께서 500000원을 출금하셨습니다.
현재 도훈님께서는 500000원을 가지고 있습니다.
선웅님께서 10000원을 입금하셨습니다.
선웅님께서 10000원을 출금하셨습니다.
현재 선웅님께서는 10000원을 가지고 있습니다.
생략...
public class Thread1 {
public static void main(String[] args) {
Tool spoon = new Tool("숟가락");
Tool chopsticks = new Tool("젓가락");
EaterThread thread1 = new EaterThread("용운", spoon, chopsticks);
EaterThread thread2 = new EaterThread("선웅", chopsticks, spoon);
thread1.start();
thread2.start();
}
}
public class Tool {
private final String name;
public Tool(String name) {
this.name = name;
}
public String toString() {
return "[ " + name + " ]";
}
}
public class EaterThread extends Thread {
private String name;
private final Tool lefthand;
private final Tool righthand;
public EaterThread(String name, Tool lefthand, Tool righthand) {
this.name = name;
this.lefthand = lefthand;
this.righthand = righthand;
}
public void run() {
while(true)
eat();
}
public void eat() {
synchronized (lefthand) {
System.out.println(name + "이가 " + lefthand + "을 (왼손) 으로 사용합니다.");
synchronized (righthand) {
System.out.println(name + "이가 " + righthand + "을 (오른손) 으로 사용합니다.");
System.out.println(name + "이가 식사를 합니다. 냠!냠!");
System.out.println(name + "이가 " + righthand + "을 (오른손) 으로 내려놓습니다.");
}
System.out.println(name + "이가 " + lefthand + "을 (왼손) 으로 내려놓습니다.");
}
}
}
결과
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
<<<<< 프로그램이 멈춘다.(교착상태 발생) >>>>>>>
public class Thread1 {
public static void main(String[] args) {
Tool spoon = new Tool("숟가락");
Tool chopsticks = new Tool("젓가락");
/*
* 선웅이용
*/
Tool spoon2 = new Tool("숟가락"); // 추가
Tool chopsticks2 = new Tool("젓가락");// 추가
EaterThread thread1 = new EaterThread("용운", spoon, chopsticks);
EaterThread thread2 = new EaterThread("선웅", chopsticks2, spoon2); // 변경
thread1.start();
thread2.start();
}
}
교착상태가 제거된 결과
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
중략 .....
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 사용합니다.
용운이가 식사를 합니다. 냠!냠!
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 사용합니다.
용운이가 WEBSTUDY: 젓가락을 (오른손) 으로 내려놓습니다.
선웅이가 식사를 합니다. 냠!냠!
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 내려놓습니다.
선웅이가 WEBSTUDY: 숟가락을 (오른손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 숟가락을 (왼손) 으로 사용합니다.
선웅이가 WEBSTUDY: 젓가락을 (왼손) 으로 내려놓습니다.
용운이가 WEBSTUDY: 젓가락을 (오른손)
public class Person_DoS extends Thread {
private String name;
private int myMoney=0;
private Bank bank;
// static private Object police = new Object(); // 경찰을 해고했다.
public Person_DoS(String name, int myMoney, Bank bank) {
this.name = name;
this.myMoney = myMoney;
this.bank = bank;
}
public void setMyMoney(int money) {
this.myMoney = money;
}
public void setMyName(String name) {
this.name = name;
}
public void run() {
synchronized(name) { // name 객체를 Lock했다.
/**
* 이 구간에서는 현재 이 메소드를 제외한 다른 메소드에서는 name을 접근할 수 없다!
*
* DoS( Denial-of-Service). name 서비스를 거부하고있다.
*
*/
bank.putMoney(myMoney);
System.out.println(name + "님께서 " + myMoney + "원을 입금하셨습니다.");
myMoney = bank.getMoney();
System.out.println(name + "님께서 " + myMoney + "원을 출금하셨습니다.");
System.out.println("현재 " + name + "님께서는 " + myMoney + "원을 가지고 있습니다.");
} // name 객체가 unLock된다.
}
}
public class ThreadGroupTest {
public static void main(String[] args) {
ThreadGroup tg1 = Thread.currentThread().getThreadGroup(); // 시스템 쓰레드
ThreadGroup tg2 = new ThreadGroup(tg1, "ThreadGroup2"); // 쓰레드 그룹 (부모:시스템 쓰레드)
ThreadGroup tg3 = new ThreadGroup("ThreadGroup3"); // 쓰레드 그룹
Thread t1 = new Thread(); // 일반 쓰레드 (자동으로 시스템쓰레드가 부모가 된다)
Thread t2 = new Thread(tg1, "Thread-tg1"); // 쓰레드1그룹 소속 쓰레드
Thread t3 = new Thread(tg2, "Thread-tg2"); // 쓰레드2그룹 소속 쓰레드
Thread t4 = new Thread(tg3, "Thread-tg3"); // 쓰레드3그룹 소속 쓰레드
/*
* 쓰레드 정보를 출력한다.
*/
System.out.println("this: "+Thread.currentThread());
System.out.println(" t1: "+t1);
System.out.println(" t2: "+t2);
System.out.println(" t3: "+t3);
System.out.println(" t4: "+t4);
/*
* 쓰레드 그룹정보를 출력한다.
*/
System.out.println("this: "+Thread.currentThread().getThreadGroup()+", "
+Thread.currentThread().getThreadGroup().activeCount()+", "
+Thread.currentThread().getThreadGroup().activeGroupCount());
System.out.println(" t1: "+t1.getThreadGroup());
System.out.println(" t2: "+t2.getThreadGroup());
System.out.println(" t3: "+t3.getThreadGroup());
System.out.println("t4:"+t4.getThreadGroup()+","+t4.getThreadGroup().getName());
Thread.currentThread().getThreadGroup().list();
}
}
결과
this: Thread[WEBSTUDY:main,5,main]
t1: Thread[WEBSTUDY:Thread-0,5,main]
t2: Thread[WEBSTUDY:Thread-tg1,5,main]
t3: Thread[WEBSTUDY:Thread-tg2,5,ThreadGroup2]
t4: Thread[WEBSTUDY:Thread-tg3,5,ThreadGroup3]
this: java.lang.ThreadGroup[WEBSTUDY:name=main,maxpri=10], 1, 2
t1: java.lang.ThreadGroup[WEBSTUDY:name=main,maxpri=10]
t2: java.lang.ThreadGroup[WEBSTUDY:name=main,maxpri=10]
t3: java.lang.ThreadGroup[WEBSTUDY:name=ThreadGroup2,maxpri=10]
t4:java.lang.ThreadGroup[WEBSTUDY:name=ThreadGroup3,maxpri=10],ThreadGroup3
java.lang.ThreadGroup[WEBSTUDY:name=main,maxpri=10]
Thread[WEBSTUDY:main,5,main]
java.lang.ThreadGroup[WEBSTUDY:name=ThreadGroup2,maxpri=10]
java.lang.ThreadGroup[WEBSTUDY:name=ThreadGroup3,maxpri=10]